package cn.com.wantools.module.nas.controller;

import cn.com.wantools.JPressConsts;
import cn.com.wantools.module.nas.model.FileNode;
import cn.com.wantools.module.nas.model.FileNodeList;
import cn.com.wantools.module.nas.model.PageExt;
import cn.com.wantools.module.nas.model.PathBreadCrumb;
import cn.com.wantools.module.nas.service.NasService;
import cn.com.wantools.web.base.AdminControllerBase;
import com.aliyun.oss.OSS;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Page;
import io.jboot.web.controller.annotation.RequestMapping;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;
import java.util.stream.Collectors;

@RequestMapping(value = "/admin/nas", viewPath = JPressConsts.DEFAULT_ADMIN_VIEW)
public class NasController extends AdminControllerBase {
    @Inject
    private NasService nasService;

    public Ret pageByPath(String path, Integer pageIndex, Integer pageSize, String nextContinuationToken) {
        String finalPath = "";
        if (StringUtils.isNotEmpty(path)) {
            finalPath = path;
        }
        if (pageIndex == null) {
            pageIndex = 1;
        }
        if (pageSize == null) {
            pageSize = 100;
        }
        OSS ossClient = null;
        Page<FileNode> fileNodePage = null;
        try {
            ossClient = nasService.createOssClient();
            int totalCount = nasService.listFileCount(ossClient, path);
            fileNodePage = nasService.pageFileNodes(ossClient, path, pageIndex, pageSize, totalCount, nextContinuationToken);
        } finally {
            nasService.shutdownOss(ossClient);
        }
        return Ret.ok().set("page", fileNodePage);

    }

    public Ret listByPath(String path, Integer pageSize, String nextContinuationToken) {
        String finalPath = "";
        if (StringUtils.isNotEmpty(path)) {
            finalPath = path;
        }
        if (pageSize == null) {
            pageSize = 100;
        }
        OSS ossClient = null;
        FileNodeList fileNodeList = null;
        try {
            ossClient = nasService.createOssClient();
            int totalCount = 100000000;
            fileNodeList = nasService.listFileNodes(ossClient, finalPath, pageSize, nextContinuationToken);

        } finally {
            nasService.shutdownOss(ossClient);
        }
        return Ret.ok().set("list", fileNodeList);
    }

//    public void index(String path, Integer pageIndex, Integer pageSize, String nextContinuationToken) {
//        String finalPath = "";
//        if (StringUtils.isNotEmpty(path)) {
//            finalPath = path;
//        }
//        if (pageIndex == null) {
//            pageIndex = 1;
//        }
//        if (pageSize == null) {
//            pageSize = 100;
//        }
//        OSS ossClient = null;
//        try {
//            ossClient = nasService.createOssClient();
//            int totalCount = nasService.listFileCount(ossClient, path);
//            Page<FileNode> fileNodePage = nasService.pageFileNodes(ossClient, path, pageIndex, pageSize, totalCount, nextContinuationToken);
//
//            setAttr("page", fileNodePage);
//        } finally {
//            nasService.shutdownOss(ossClient);
//        }
//        render("nas/nas_index_new.html");
//    }

    public void indexNew(String path, Integer pageIndex, Integer pageSize, String nextContinuationToken) {
        path = path == null ? "" : path;
        String[] pathArr = path.split("/");
        List<PathBreadCrumb> pathList = new ArrayList<>();
        for (String pathItem: pathArr) {
            String lastPath = pathList.size() == 0 ? "" : pathList.get(pathList.size() - 1).getPath();
            PathBreadCrumb pathBreadCrumb = new PathBreadCrumb();
            pathBreadCrumb.setTitle(pathItem);
            pathBreadCrumb.setPath(lastPath + pathItem + "/");
            pathList.add(pathBreadCrumb);
        }
        setAttr("path", path);
        setAttr("pathList", pathList);
        render("nas/nas_index_new.html");
    }

    public void findDuplicateFiles(String path) {
        String finalPath = "";
        if (StringUtils.isNotEmpty(path)) {
            finalPath = path;
        }

        int pageIndex = 1;
        int pageSize = 100;
        OSS ossClient = null;
        try {
            ossClient = nasService.createOssClient();
            //int totalCount = nasService.listFileCount(ossClient, path);
            int count = 0;
            List<FileNode> fileNodeList = new ArrayList<>();
            String nextContinuationToken = null;
            boolean hasNext = false;
            do {
                PageExt<FileNode> fileNodePage = nasService.listAllFileNodesWithSubFolder(ossClient, path, pageIndex, pageSize, 100000000, nextContinuationToken);
                nextContinuationToken = fileNodePage.getNextContinuationToken();
                if (fileNodePage.isTruncted()) {
                    hasNext = true;
                } else {
                    hasNext = false;
                }
                fileNodeList.addAll(fileNodePage.getList());
                count += fileNodePage.getList().size();
            } while (hasNext);
            Map<String, List<FileNode>> fileMap = new HashMap<>();
            OSS finalOssClient = ossClient;
            fileNodeList.stream().forEach(node -> {
                String eTag = nasService.getETag(finalOssClient, node.getPath());
                Long size = node.getSize();
                if (!fileMap.containsKey(eTag + "_" + size)) {
                    fileMap.put(eTag + "_" + size, new ArrayList<FileNode>());
                }
                fileMap.get(eTag + "_" + size).add(node);
            });
            List<List<FileNode>> list = fileMap.values().stream().filter(i -> i.size() > 1).collect(Collectors.toList());
            //FileUtils.writeStringToFile(new File("duplicateFile"), list.stream().map(m -> m.stream().map(s -> s.getPath()).collect(Collectors.));
            StringBuffer tmp = new StringBuffer();
            for (List<FileNode> l : list) {
                tmp.append("========================\n");
                for (FileNode node : l) {
                    tmp.append(node.getPath() + "\n");
                }
            }
            FileUtils.write(new File("duplicateFile"), tmp.toString(), Charset.defaultCharset());
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            nasService.shutdownOss(ossClient);
        }

        //setAttr("fileMap", fileMap);
        render("nas/nas_index.html");
    }

    public Ret showImgFile(String path) {
        OSS ossClient = null;
        String url = null;
        try {
            ossClient = nasService.createOssClient();
            url = nasService.showImageUrl(ossClient, path, false);
            setAttr("url", url);
        } finally {
            nasService.shutdownOss(ossClient);
        }
        return new Ret().setOk().set("url", url);
    }

    public void deleteDuplicateFile() throws IOException {
        List<String> fileNameList = FileUtils.readLines(new File("duplicateFile"), Charset.defaultCharset());
        OSS ossClient = null;
        String bucketName = "nas-wxx";
        try {
            ossClient = nasService.createOssClient();
            for (String key: fileNameList) {
                if (key.equals("")) {
                    continue;
                }
                if (key.substring(key.length() - 1).equals("/")) {
                    continue;
                }
                ossClient.deleteObject(bucketName, key);
            }
        } catch (Exception oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getMessage());
        } finally {
            nasService.shutdownOss(ossClient);
        }
    }

    public Ret showFileUrl(String path) {
        OSS ossClient = null;
        String url = null;
        try {
            ossClient = nasService.createOssClient();
            url = nasService.showFileUrl(ossClient, path);
            setAttr("url", url);
        } finally {
            nasService.shutdownOss(ossClient);
        }
        return new Ret().setOk().set("url", url);
    }


    public Ret showMediaFile(String path) {
        OSS ossClient = null;
        String url = null;
        try {
            ossClient = nasService.createOssClient();
            url = nasService.showMediaUrl(ossClient, path);
            setAttr("url", url);
        } finally {
            nasService.shutdownOss(ossClient);
        }
        return new Ret().setOk().set("url", url);
    }

    public Ret showDocFile(String path) {
        OSS ossClient = null;
        String url = null;
        try {
            ossClient = nasService.createOssClient();
            url = nasService.showDocFileUrl(ossClient, path);
            setAttr("url", url);
        } finally {
            nasService.shutdownOss(ossClient);
        }
        return new Ret().setOk().set("url", url);
    }
}
